package com.qining618.common.utils.http;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author iqiao
 * @date 2019/8/27 0027.
 */
@Slf4j
public class LocalHttpClient {

    protected static final Header userAgentHeader;
    protected static CloseableHttpClient httpClient;
    private static int timeout = 8000;
    private static int retryExecutionCount = 2;
    private static Map<String, CloseableHttpClient> httpClient_mchKeyStore;

    static {
        httpClient = HttpClientFactory.createHttpClient(100, 10, timeout, retryExecutionCount);
        httpClient_mchKeyStore = new ConcurrentHashMap();
        userAgentHeader = new BasicHeader("User-Agent", "game-api java v1.0.0");
    }

    public LocalHttpClient() {
    }

    public static CloseableHttpResponse execute(HttpUriRequest request) {
        loggerRequest(request);
        userAgent(request);
        try {
            return httpClient.execute(request, HttpClientContext.create());
        } catch (Exception e) {
            log.error("execute error", e);
        }
        return null;
    }

    public static <T> T execute(HttpUriRequest request, ResponseHandler<T> responseHandler) {
        String uriId = loggerRequest(request);
        userAgent(request);
        if (responseHandler instanceof LocalResponseHandler) {
            LocalResponseHandler lrh = (LocalResponseHandler) responseHandler;
            lrh.setUriId(uriId);
        }
        try {
            T t = httpClient.execute(request, responseHandler, HttpClientContext.create());
            return t;
        } catch (Exception e) {
            log.error("execute error", e);
        }
        return null;
    }

    /**
     * 数据返回字符串
     *
     * @param request request
     * @return result
     */
    public static String executeStringResult(HttpUriRequest request) {
        return execute(request, StringResponseHandler.createResponseHandler());
    }

    /**
     * 数据返回自动JSON对象解析
     *
     * @param request request
     * @param clazz   clazz
     * @param <T>     T
     * @return result
     */
    public static <T> T executeJsonResult(HttpUriRequest request, Class<T> clazz) {
        return execute(request, JsonResponseHandler.createResponseHandler(clazz));
    }

    private static String loggerRequest(HttpUriRequest request) {
        String id = UUID.randomUUID().toString();
        if (log.isInfoEnabled() || log.isDebugEnabled()) {
            if (request instanceof HttpEntityEnclosingRequestBase) {
                HttpEntityEnclosingRequestBase request_base = (HttpEntityEnclosingRequestBase) request;
                HttpEntity entity = request_base.getEntity();
                String content = null;
                if (entity.getContentType().toString().indexOf(ContentType.MULTIPART_FORM_DATA.getMimeType()) == -1) {
                    try {
                        content = EntityUtils.toString(entity);
                    } catch (Exception var6) {
                        log.error("logger content data get error", var6);
                    }
                }

                log.info("URI[{}] {} {} ContentLength:{} Content:{}", id, request.getURI().toString(), entity.getContentType(), entity.getContentLength(), content == null ? "multipart_form_data" : content);
            } else {
                log.info("URI[{}] {}", id, request.getURI().toString());
            }
        }

        return id;
    }

    private static void userAgent(HttpUriRequest httpUriRequest) {
        httpUriRequest.addHeader(userAgentHeader);
    }
}
